#include "uartcom.h"
#include "Usart.h"
#include <stdio.h>

//STATIC OR GLOBLE INITIAL
TinyFrame *gpMcuTf = NULL;

//FUNCTION
//TinyFrame Start===================================================================
/**
 * This is an example of integrating TinyFrame into the application.
 * 
 * TF_WriteImpl() is required, the mutex functions are weak and can
 * be removed if not used. They are called from all TF_Send/Respond functions.
 * 
 * Also remember to periodically call TF_Tick() if you wish to use the 
 * listener timeout feature.
 */
//Global VAR

//硬件写出
//[TODO]对接MCU串口数据写出接口
void TF_WriteImpl(TinyFrame *tf, const uint8_t *buff, uint32_t len)
{
		uint32_t index = 0;
		// send to UART
		while(index < len){
			//USART_SendData(USART2, (uint8_t) buff[index]);
			USART2_Send485Data((uint8_t) buff[index]);
			USART3_Send485Data((uint8_t) buff[index]);
			
			++index;
		}
}

// --------- Mutex callbacks ----------
// Needed only if TF_USE_MUTEX is 1 in the config file.
// DELETE if mutex is not used

/** Claim the TX interface before composing and sending a frame */
bool TF_ClaimTx(TinyFrame *tf)
{
    // take mutex
    return true; // we succeeded
}

/** Free the TX interface after composing and sending a frame */
void TF_ReleaseTx(TinyFrame *tf)
{
    // release mutex
}

// --------- Custom checksums ---------
// This should be defined here only if a custom checksum type is used.
// DELETE those if you use one of the built-in checksum types

/** Initialize a checksum */
// TF_CKSUM TF_CksumStart(void)
// {
// return 0;
// }

// /** Update a checksum with a byte */
// TF_CKSUM TF_CksumAdd(TF_CKSUM cksum, uint8_t byte)
// {
// return cksum ^ byte;
// }

// /** Finalize the checksum calculation */
// TF_CKSUM TF_CksumEnd(TF_CKSUM cksum)
// {
// return cksum;
// }
//TinyFrame End===================================================================
//注册的MCU数据监听回调
UC_RESULT McuListener(TinyFrame *tf, UC_MSG *msg)
{
    DumpFrameInfo(msg);
    return TF_STAY;
}

//Uart protocol inital
//[TODO]对接MCU串口解析协议解析初始化,请在程序初始化时候调用它
void UartProtocolInit(void)
{
    // Set up the TinyFrame library
    gpMcuTf = TF_Init(TF_MASTER); // 1 = master, 0 = slave
		if( gpMcuTf != NULL){
			TF_AddGenericListener(gpMcuTf, McuListener);
			printf("UartProtocolInit [OK].\n\r");
		}else{
			 printf("UartProtocolInit [FAIL].\n\r");
		}
}

//UART收到数据push到协议
//对接MCU串口数据接收接口，讲数据Push到协议解析层
int PushBuffToTf(char *pBuf, int iLen)
{
		if(gpMcuTf != NULL){
			TF_Accept(gpMcuTf, (const uint8_t *)pBuf, iLen);
			return 0;
		}else{
			return -1;
		}
}

//Dump msg data
void DumpFrameInfo(UC_MSG *msg)
{
    printf("\033[33m\r\n===Frame info===\n\r"
           "  type: %02Xh\n\r"
           "  data: \"%.*s\"\n\r"
           "   len: %u\n\r"
           "    id: %Xh\033[0m\n\n\r",
           msg->type, msg->len, msg->data, msg->len, msg->frame_id);
	
		for(uint8_t i = 0; i< msg->len; ++i){
			printf("%02Xh ",msg->data[i]);
		}
}

//=====================================================
//用户层发送数据接口，请参考tinyframe.h文件内函数定义使用
//=====================================================

#if 0
//用户层调用参考代码
void main(void)
{
		char rec_buff[16] = {0};
		int irec_len= 0;
		//1. inital uart hw
	  //[TODO] uart hw inital
		
	  //2. inital uart protocol
		UartProtocolInit();
	
	  //3. loop read uart data from hw
		while(true){
			//[TODO] fill  rec_buff data and irec_len
			PushBuffToTf(rec_buff, irec_len);
		}
}
#endif

